home *** CD-ROM | disk | FTP | other *** search
- /**********************************************************************
- *
- * dctvgrad.c - Render a 24-bit RGB gradient visible on DCTV.
- *
- * Copyright (C) 1991, 1992 Digital Creations, Inc.
- *
- * DESCRIPTION
- * This example demonstrates how to call dctv.library to generate a
- * DCTV frame by suppling lines of 24-bit RGB data (in this case a
- * multi-point gradient). The finished BitMap can then be written
- * to an ILBM file.
- *
- * Program runs under Amiga OS v1.3 and higher.
- *
- * USAGE
- * dctvgrad <width> <height> <depth>
- * width - screen width (640..736)
- * height - screen height (200..241, 400..482)
- * depth - screen depth (3..4)
- *
- * Terminate with Control+C.
- *
- * COMPILATION
- * SAS/C: (v5.10 or higher. Regular of ANSI libs)
- * lc -L+dctv.lib dctvgrad
- *
- * Aztec C: (v5.0a or higher)
- * cc dctvgrad [works w/ either 16 or 32 bit int's]
- * ln dctvgrad.o +l dctv.lib -lc
- *
- * REQUIREMENTS
- * . Aztec C 5.0 or SAS/C 5.10.
- * . v37.4 or higher Amiga include files.
- * . OS #pragmas created for your compiler in the pragmas
- * directory of your include path.
- *
- **********************************************************************/
-
- #include <dos/dos.h>
- #include <intuition/screens.h>
- #include <libraries/dctv.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
-
- #include <clib/dctv_protos.h>
- #include <clib/exec_protos.h>
- #include <clib/graphics_protos.h>
- #include <clib/intuition_protos.h>
-
- #include <pragmas/dctv_pragmas.h>
- #include <pragmas/exec_pragmas.h>
- #include <pragmas/graphics_pragmas.h>
- #include <pragmas/intuition_pragmas.h>
-
-
- /* -------------------- misc defines */
-
- #define DCTVLIB_Version 3
-
-
- /* -------------------- data */
-
- struct Library *DCTVBase, *GfxBase, *IntuitionBase;
-
-
- /* -------------------- local functions */
-
- /* screen processor */
- void doscreen (short width, short height, short depth);
-
- /* gradient functions */
- void initgrad (struct DCTVCvtHandle *);
- void rendergradline (struct DCTVCvtHandle *);
-
-
- /* -------------------- main() */
-
- #if AZTEC_C
- void _wb_parse (void) {} /* stub out wb window parser */
- #endif
-
- #if __SASC /* suppress normal Ctrl-C processing (SAS/C) */
- void __chkabort (void) {}
- void chkabort (void) {}
- #endif
-
- int main (int argc, char **argv)
- {
- if (argc < 4) goto clean;
-
- #if AZTEC_C /* suppress normal Ctrl-C processing (Aztec C) */
- {
- extern int Enable_Abort;
- Enable_Abort = 0;
- }
- #endif
-
- if (!(IntuitionBase = OpenLibrary ("intuition.library", LIBRARY_MINIMUM))) goto clean;
- if (!(GfxBase = OpenLibrary ("graphics.library", LIBRARY_MINIMUM))) goto clean;
- if (!(DCTVBase = OpenLibrary ("dctv.library", DCTVLIB_Version))) {
- printf ("requires dctv.library v%d\n", DCTVLIB_Version);
- goto clean;
- }
-
- doscreen (atoi(argv[1]), atoi(argv[2]), atoi(argv[3]));
-
- clean:
- if (DCTVBase) CloseLibrary (DCTVBase);
- if (GfxBase) CloseLibrary (GfxBase);
- if (IntuitionBase) CloseLibrary (IntuitionBase);
- return 0;
- }
-
-
- /* -------------------- doscreen() */
-
- struct Screen *openscreen (short width, short height, short depth);
- struct DCTVCvtHandle *alloccvt (struct Screen *);
-
- void doscreen (short width, short height, short depth)
- {
- struct Screen *screen = NULL;
- struct DCTVCvtHandle *cvt = NULL;
-
- /* Open a screen (also conveniently creates a BitMap for use with dctv.library). */
- if (!(screen = openscreen (width, height, depth))) goto clean;
-
- /* Allocate DCTV conversion environment. */
- if (!(cvt = alloccvt (screen))) goto clean;
-
- /* Initialize Screen colors and format BitMap for a black DCTV display. */
- LoadRGB4 (&screen->ViewPort, cvt->ColorTable, cvt->NColors);
- FormatDCTV (cvt);
-
- /* Make a frame. */
- initgrad (cvt); /* Init gradient data. */
-
- /*
- Line rendering loop.
-
- Loop until all Destination lines have been converted
- (indicated by DstLineNum >= height).
-
- Because the filter process introduces an N-line delay
- between source and destination lines, you must call
- CvtDCTVLine() until all the destination lines have been
- converted. That means the code in this loop will be
- executed (height + NDelayLines) times.
-
- Your rendering code should use SrcLineNum to indicate which
- line to render. CvtDCTVLine() ignores the RGB line buffer for
- SrcLineNum values outside the range of the ImageBounds
- rectangle. SrcLineNum is in the range of
- 0 <= SrcLineNum < Height+NDelayLines before each call; avoid
- overindex your rendering code.
- */
- while (cvt->DstLineNum < cvt->Height) {
-
- /* Abort on Ctrl-C. */
- if (SetSignal (0, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) goto clean;
-
- rendergradline (cvt); /* Render a line of the gradient to
- DCTVCvtHandle RGB line buffer.
- This function is smart enough to
- handle line #'s out of range. */
-
- CvtDCTVLine (cvt); /* Convert the line in the line buffer to
- DCTV display data. Results in rendering
- a line of the BitMap. */
- }
-
- Wait (SIGBREAKF_CTRL_C); /* Wait until user types Control+C
- into shell window before quitting. */
-
- clean:
- if (cvt) FreeDCTVCvt (cvt);
- if (screen) CloseScreen (screen);
- }
-
- struct Screen *openscreen (short width, short height, short depth)
- {
- static struct NewScreen newscreen = {
- 0, 0, 0, 0, 0,
- -1, -1,
- 0,
- CUSTOMSCREEN | SCREENQUIET,
- NULL,
- "dctvgrad",
- NULL,
- NULL
- };
- struct Screen *screen;
-
- newscreen.Width = width + 15 & ~15; /* pad width to next multiple of 16 */
- newscreen.Height = height;
- newscreen.Depth = depth;
- newscreen.ViewModes = height > 350 ? HIRESLACE_KEY : HIRES_KEY;
-
- if (!(screen = OpenScreen (&newscreen))) {
- puts ("OpenScreen failed\n");
- }
-
- return screen;
- }
-
- struct DCTVCvtHandle *alloccvt (struct Screen *screen)
- {
- ULONG flags = 0;
- struct DCTVCvtHandle *cvt;
- ULONG errcode;
-
- if (screen->ViewPort.Modes & LACE) flags |= DCTVCVTF_Lace;
- if (!(cvt = AllocDCTVCvtTags ( screen->RastPort.BitMap,
- DCTVCVTA_Type, (ULONG)DCTVCVTT_RGBtoDCTV,
- DCTVCVTA_Width, (ULONG)screen->Width,
- DCTVCVTA_Height, (ULONG)screen->Height,
- DCTVCVTA_Flags, (ULONG)flags,
- DCTVCVTA_ErrorCode, &errcode,
- TAG_END ))) {
- printf ("AllocDCTVCvtTags failed %lu\n", errcode);
- }
-
- return cvt;
- }
-
-
- /* -------------------- 24-bit RGB gradient functions */
-
- #define gcent(m,l) (((m)-(l)) / 2) /* centering macro */
-
- void initgrad (struct DCTVCvtHandle *cvt)
- {
- short bufwidth = cvt->Width;
- short imagewidth = cvt->ImageBounds.MaxX - cvt->ImageBounds.MinX + 1;
- short i;
-
- /* init line to black */
- memset (cvt->Red, 0, bufwidth);
- memset (cvt->Green, 0, bufwidth);
- memset (cvt->Blue, 0, bufwidth);
-
- /* ramp red horizontally */
- for (i=0; i < imagewidth; i++)
- cvt->Red [i+cvt->ImageBounds.MinX] = (ULONG)i * 255 / imagewidth;
- }
-
- void rendergradline (struct DCTVCvtHandle *cvt)
- {
- short imagewidth = cvt->ImageBounds.MaxX - cvt->ImageBounds.MinX + 1;
- short imageheight = cvt->ImageBounds.MaxY - cvt->ImageBounds.MinY + 1;
- short y = cvt->SrcLineNum - cvt->ImageBounds.MinY;
- short bluewidth;
- UBYTE greenval;
-
- if (y >= 0 && y < imageheight) {
- /* constant green component for line */
- greenval = (long)y * 255 / imageheight;
- memset (cvt->Green + cvt->ImageBounds.MinX, greenval, imagewidth);
-
- /* reverse wedge blue component */
- bluewidth = (long)(imageheight - y) * imagewidth / imageheight;
- if (bluewidth > 0)
- memset (cvt->Blue + gcent (imagewidth, bluewidth) + cvt->ImageBounds.MinX, 255-greenval, bluewidth);
- }
- }
-